#!/usr/bin/with-contenv bashio
# vim: ft=bash
# shellcheck shell=bash
# ==============================================================================
# Send deCONZ discovery information to Home Assistant
# ==============================================================================
declare api_key
declare config
declare retries
declare serial

bashio::log.info "Starting discovery script..."

# Wait for deCONZ to start before continuing
bashio::net.wait_for 40850

# Remove old discovery data storage (cleanup)
# We now query the deCONZ database for it directly.
if bashio::fs.file_exists /data/hassio.json; then
    rm /data/hassio.json
fi

# Locate database
DATA_STORE="/data/.local/share/deCONZ/zll.db"
if [ ! -f "$DATA_STORE" ]; then
    bashio::log.warning "Database not found at $DATA_STORE, trying alternative path..."
    DATA_STORE="/data/.local/share/dresden-elektronik/deCONZ/zll.db"
    if [ ! -f "$DATA_STORE" ]; then
        bashio::log.error "No database found in either path! Proceeding without serial."
        DATA_STORE=""
    fi
fi

# Read API key from database
if [ -n "$DATA_STORE" ]; then
    api_key=$(sqlite3 "${DATA_STORE}" \
        'SELECT apikey FROM auth WHERE devicetype="Home Assistant" ORDER BY createdate DESC LIMIT 1' 2>/dev/null)
fi

# Test API key immediately, if available
if [ -n "$api_key" ]; then
    http_code=$(curl -s -o /dev/null -w "%{http_code}" \
        "http://127.0.0.1:40850/api/${api_key}/config")
    if [[ "$http_code" != "200" ]]; then
        bashio::log.warning "Existing API key invalid (HTTP $http_code), will try to create a new one..."
        api_key=""
    else
        bashio::log.info "Existing API key is valid."
    fi
fi

# Try to create API key if none exists
if ! bashio::var.has_value "${api_key}"; then
    bashio::log.warning "No API key found – trying to create a new one..."
    for i in $(seq 1 60); do
        if result="$(curl --silent --show-error --request POST \
            -d '{"devicetype": "Home Assistant"}' \
            "http://127.0.0.1:40850/api")"; then
            api_key="$(bashio::jq "${result}" '.[0].success.username')"
            if bashio::var.has_value "${api_key}"; then
                bashio::log.info "API key successfully created after ${i} seconds."
                break
            fi
        fi
        sleep 1
    done
    if ! bashio::var.has_value "${api_key}"; then
        bashio::log.error "Failed to get an API key from deCONZ – continuing without discovery."
        exit 0
    fi
fi

# Get serial/bridge ID
retries=25
serial="0000000000000000"
while [[ "${serial}" = "0000000000000000" && "${retries}" -gt 0 ]]; do
    sleep 5
    if result="$(curl --silent --show-error \
        --request GET "http://127.0.0.1:40850/api/${api_key}/config")"; then
        candidate="$(bashio::jq "${result}" '.bridgeid')"
        if [[ "$candidate" =~ ^[0-9A-Fa-f]{16}$ ]]; then
            serial="$candidate"
        else
            serial="0000000000000000"
        fi
    fi
    ((retries--))
done

if [[ "${serial}" = "0000000000000000" ]]; then
    bashio::log.error "Failed to get a valid bridge ID – continuing without discovery."
    exit 0
fi

# Create config payload for Home Assistant
config=$(bashio::var.json \
    host "$(hostname)" \
    port "^40850" \
    api_key "${api_key}" \
    serial "${serial}" \
)

# Send discovery info
if bashio::discovery "deconz" "${config}" > /dev/null; then
    bashio::log.info "Successfully sent discovery information to Home Assistant."
else
    bashio::log.error "Failed to send discovery message to Home Assistant!"
fi
